﻿using Gengens.Disk.Entity.bean;
using Gengens.Disk.Entity.model.user;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.Extensions.Logging;
using System.Data;
using System.Reflection;
using System.Text;

namespace Gengens.Disk.Entity;

public class AppDbCtx : DbContext
{
    private List<ModelInfo> _modelInfos;
    public List<ModelInfo> ModelInfos
    {
        get
        {
            _modelInfos ??= new();
            return _modelInfos;
        }
        set => _modelInfos = value;
    }

    private readonly ILogger _logger;
    private readonly AppDbCtxConfig _config;

    public AppDbCtx(ILogger<AppDbCtx> logger, AppDbCtxConfig config) : base(new DbContextOptions<AppDbCtx>())
    {
        _logger = logger;
        _config = config;
        ModelInfos = config.modelInfos;
        _logger.LogInformation($"数据上下文启动，加载到{ModelInfos.Count}个模型");
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        if (ModelInfos.Count == 0)
        {
            _logger.LogInformation("模型库中没有模型");
            return;
        }

        Type mbType = modelBuilder.GetType();
        MethodInfo executeMd = mbType.GetMethods().FirstOrDefault(m => m.Name.Equals("Entity", StringComparison.OrdinalIgnoreCase) && m.ContainsGenericParameters);

        foreach (var model in ModelInfos)
        {
            modelBuilder.Entity(model.Type);
            MethodInfo onModelCreate = model.Type.GetMethod("OnModelCreate");

            StringBuilder sr = new StringBuilder();

            object param = executeMd.MakeGenericMethod(model.Type).Invoke(modelBuilder, null);

            onModelCreate.Invoke(model.Instance, new object[] { param });
        }

        _logger.LogInformation($"{ModelInfos.Count}个模型的创建模型生命周期方法执行完毕");
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(_config.ConnectString);
        base.OnConfiguring(optionsBuilder);
    }



}

